package ar.com.sudoku.factories;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import ar.com.sudoku.exceptions.InvalidSudokuException;
import ar.com.sudoku.model.ArrayGrid;
import ar.com.sudoku.model.ForceBruteSudoku;
import ar.com.sudoku.model.SudokuNumber;
import ar.com.sudoku.rules.ColumnRule;
import ar.com.sudoku.rules.RowRule;
import ar.com.sudoku.rules.Rule;
import ar.com.sudoku.rules.SquareRule;

public class RandomSudokuBuilder extends SudokuBuilder {

	@Override
	public void setStrategy() {
		sudoku = new ForceBruteSudoku();
		Set<Rule> rules = new HashSet<Rule>();
	    rules.add(new ColumnRule());
	    rules.add(new RowRule());
	    rules.add(new SquareRule());
	    sudoku.setRules(rules);
	}

	@Override
	public void setGrid() {
		sudoku.setGrid(new ArrayGrid());
	}
	
	@Override
	public void fillSudoku(short cells) {
		if (cells < 0 || cells > 81) {
			throw new IllegalArgumentException("Max 81 cells - Min cells 0");
		}
		if (cells == 0) {
			return;
		}
		List<SudokuNumber> values = Arrays.asList(SudokuNumber.values());
		Collections.shuffle(values);
		SudokuNumber randomNumber = SudokuNumber.random();
		if (randomNumber.getValue() < 5) {
			for (SudokuNumber y : SudokuNumber.values()) {
				sudoku.getGrid().set(randomNumber,y,values.get(y.getValue()-1));
			}
		} else {
			for (SudokuNumber x : SudokuNumber.values()) {
				sudoku.getGrid().set(x,randomNumber,values.get(x.getValue()-1));
			}
		}
		try {
			Long time = System.currentTimeMillis();
			sudoku.solve();
			time = System.currentTimeMillis() - time;
			if (time > 1000) {
				System.out.println("solve " + time);
			}
		} catch (InvalidSudokuException e) {
			throw new RuntimeException("Bugggggg, creando un sudoku que no se puede resolver",e);
		}
		if (cells == 81) {
			return;
		}
		List<Short> positions = new ArrayList<Short>();
		for (short position = 1; position <= 81; position++) {
			positions.add(position);
		}
		Collections.shuffle(positions);
		positions = positions.subList(1,81-cells);
		short position = 1;
		for (SudokuNumber x : SudokuNumber.values()) {
			for (SudokuNumber y : SudokuNumber.values()) {
				if (positions.contains(position)) {
					sudoku.getGrid().set(x,y,null);
				}
				position++;
			}
		}
		int x = 0;
		x++;
	}

}
